import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import static java.lang.System.out;  //debugging

/** Class Volleyball */
public class Volleyball extends JFrame implements ActionListener, ItemListener {
        private JMenuBar menuBar;
        private JMenu fileMenu, formatMenu, outOfBoundsColorMenu, 
                      courtColorMenu, lineColorMenu, actionMenu, movePlyrsMenu, 
                      optionsMenu, formationMenu;
        private JMenuItem exitMenuItem;
        private JRadioButtonMenuItem customOB, customCC, customLC,
                                     rotationButton, rcvStartingFormationBtn, 
                                     serveFormationBtn, formation62, 
                                     formation42;
        private JCheckBox showNamesBox, showRolesBox;
	private Color bgColor, courtColor, lineColor;
        private Court court;
        private Container contentPane;

        /** Constructor */
	public Volleyball () {
		this.setLayout(new BorderLayout());
		               
                //set JMenuBar (Top Bar)
                //File menu
		menuBar = new JMenuBar();
		fileMenu = new JMenu("File");
		fileMenu.setMnemonic('F');
		menuBar.add(fileMenu);
		exitMenuItem = new JMenuItem("Exit");
		exitMenuItem.setMnemonic('E');
		exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_MASK));
		exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0));
		exitMenuItem.addActionListener(this);                
		fileMenu.add(exitMenuItem);
                
                //Format menu
		formatMenu = new JMenu("Format");
		formatMenu.setMnemonic('O');
		menuBar.add(formatMenu);
                	
		//outOfBoundsColor
		outOfBoundsColorMenu = new JMenu("Out-of-Bounds Color");
		outOfBoundsColorMenu.setMnemonic('B');
		ButtonGroup outOfBoundsColorGrp = new ButtonGroup();
		customOB = new JRadioButtonMenuItem("Customize Color", true);
		customOB.setMnemonic('G');
		customOB.addActionListener(this);
		outOfBoundsColorGrp.add(customOB);
		outOfBoundsColorMenu.add(customOB);
		formatMenu.add(outOfBoundsColorMenu);
		
		//courtColor
		courtColorMenu = new JMenu("Court Color");
		courtColorMenu.setMnemonic('C');
		ButtonGroup courtColorGrp = new ButtonGroup();
		customCC = new JRadioButtonMenuItem("Customize Color", true);
		customCC.setMnemonic('G');
		customCC.addActionListener(this);
		courtColorGrp.add(customCC);
		courtColorMenu.add(customCC);
		formatMenu.add(courtColorMenu);
                
		//lineColor
		lineColorMenu = new JMenu("Line Color");
		lineColorMenu.setMnemonic('L');
		ButtonGroup lineColorGrp = new ButtonGroup();
		customLC = new JRadioButtonMenuItem("Customize Color", true);
		customLC.setMnemonic('G');
		customLC.addActionListener(this);
		lineColorGrp.add(customLC);
		lineColorMenu.add(customLC);
		formatMenu.add(lineColorMenu);
                
                //Actions menu
                actionMenu = new JMenu("Actions");
		actionMenu.setMnemonic('O');
		menuBar.add(actionMenu);
                
                //Move Players menu
                movePlyrsMenu = new JMenu("Move Players");
		movePlyrsMenu.setMnemonic('M');
		actionMenu.add(movePlyrsMenu);
               
                //Rotation button
		ButtonGroup rotationGrp = new ButtonGroup();
		rotationButton = new JRadioButtonMenuItem("Rotate Clockwise", true);
		rotationButton.setMnemonic('R');
		rotationButton.addActionListener(this);
		rotationGrp.add(rotationButton);
                movePlyrsMenu.add(rotationButton);
                
                //Serve formation buttons
		ButtonGroup servePosGrp = new ButtonGroup();
		rcvStartingFormationBtn = new JRadioButtonMenuItem("Receive Serve Formation", false);
		rcvStartingFormationBtn.setMnemonic('R');
		rcvStartingFormationBtn.addActionListener(this);
		servePosGrp.add(rcvStartingFormationBtn);
                movePlyrsMenu.add(rcvStartingFormationBtn);
                serveFormationBtn = new JRadioButtonMenuItem("Team Serve Formation", false);
		serveFormationBtn.setMnemonic('S');
		serveFormationBtn.addActionListener(this);
		servePosGrp.add(serveFormationBtn);
                movePlyrsMenu.add(serveFormationBtn);
                
                //Options menu
                optionsMenu = new JMenu("Options");
		optionsMenu.setMnemonic('O');
		menuBar.add(optionsMenu);
                
                //Formation menu
                formationMenu = new JMenu("Formations");
		formationMenu.setMnemonic('F');
                ButtonGroup formationGrp = new ButtonGroup();
		formation62 = new JRadioButtonMenuItem("Formation 6-2", false);
		formation62.setMnemonic('6');
		formation62.addActionListener(this);
		formationGrp.add(formation62);
                formationMenu.add(formation62);
                formation42 = new JRadioButtonMenuItem("Formation 4-2", true);
                formation42.setMnemonic('4');
		formation42.addActionListener(this);
                formationGrp.add(formation42);
                formationMenu.add(formation42);
		optionsMenu.add(formationMenu);
                
                //Show names checkbox
		showNamesBox = new JCheckBox("Show player names");
                showNamesBox.setMnemonic(KeyEvent.VK_C);
                showNamesBox.setSelected(true);
                showNamesBox.addItemListener(this);
                optionsMenu.add(showNamesBox);
                
                //Show positions checkbox
		showRolesBox = new JCheckBox("Show player roles");
                showRolesBox.setMnemonic(KeyEvent.VK_C);
                showRolesBox.setSelected(true);
                showRolesBox.addItemListener(this);
                optionsMenu.add(showRolesBox);
		
		//add menuBar
		this.add(menuBar, BorderLayout.NORTH);
                
                //add court
                contentPane = this.getContentPane();
                court = new Court();
		contentPane.add(court);   
	}
        
        public void addPlayer(String imagePath, int x, int y, Player.Position pos) {
            //add player
            court.addPlayer(imagePath, x, y, pos);
	}
        
        public void addPlayer(String imagePath, int x, int y, Player.Height height,
                              Player.Position pos) {
            //add player
            court.addPlayer(imagePath, x, y, height, pos);
	}
        
        public void addPlayer(String imagePath, int x, int y, String name, 
                              Player.Height height, 
                              Player.Position pos,
                              Player.Role role) {
            //add player
            court.addPlayer(imagePath, x, y, name, height, pos, role);
	}
        
        public void setTeamFormation(Court.Formation form){
            court.setTeamFormation(form);
        }
	
        /** ActionListener */
	public void actionPerformed(ActionEvent e) {
            //user selects Exit from Top Menu
            if (e.getSource() == exitMenuItem) {
                System.exit(0);
            }
            //user selects 'Change Out-of-Bounds Color' from Top Menu
            else if (e.getSource() == customOB) {			
                court.setBackgroundColor(JColorChooser.showDialog(this, "Choose a color", bgColor));
            }
            //user selects 'Change Court Color' from Top Menu
            else if (e.getSource() == customCC) {
                court.setCourtColor(JColorChooser.showDialog(this, "Choose a color", courtColor));
            }
            //user selects 'Change Line Color' from Top Menu
            else if (e.getSource() == customLC) {
                court.setLineColor(JColorChooser.showDialog(this, "Choose a color", lineColor));
            }
            //user selects 'Rotate Players' button from Options Menu
            else if (e.getSource() == rotationButton) {
                //rotate players on court
                court.rotatePlayers();
                //change player roles based on court positions
                court.setTeamFormation(court.getTeamFormation());
            }
            //user selects 'Formation 6-2' button from Formation Menu
            else if (e.getSource() == formation62) {
                //set formation
                out.println("User selected Formation 6-2");
                court.setTeamFormation(Court.Formation.FORMATION_6_2);
            }
            //user selects 'Formation 4-2' button from Formation Menu
            else if (e.getSource() == formation42) {
                //set formation
                out.println("User selected Formation 4-2");
                court.setTeamFormation(Court.Formation.FORMATION_4_2);
            }
            //user selects 'Receive Serve Formation' button from Options Menu
            else if (e.getSource() == rcvStartingFormationBtn) {
                //set formation
                out.println("User selected Receive Serve Formation");
                court.setStartingTeamFormation(Court.StartingFormation.FORMATION_RECEIVE_SERVE);
            }
            //user selects 'Team Serve Formation' button from Options Menu
            else if (e.getSource() == serveFormationBtn) {
                //set formation
                out.println("User selected Team Serve Formation");
                court.setStartingTeamFormation(Court.StartingFormation.FORMATION_TEAM_SERVE);
            }
            else {
                out.println("Ignored action: " + e.getSource());
            }
	}
        
        /** ItemListener */
        public void itemStateChanged(ItemEvent e) {
            //user selects 'Show names' box from Options Menu
            if (e.getSource() == showNamesBox) {
                if (e.getStateChange() == ItemEvent.DESELECTED){
                    court.setShowNamesAttribute(false);
                }
                else {court.setShowNamesAttribute(true);}
            }
            //user selects 'Show positions' box from Options Menu
            else if (e.getSource() == showRolesBox) {
                if (e.getStateChange() == ItemEvent.DESELECTED){
                    court.setShowRolesAttribute(false);
                }
                else {court.setShowRolesAttribute(true);}
            }
        }
	
	/** main */
	public static void main (String[] args) {
                //create window object and set attributes
		Volleyball vball = new Volleyball();
		vball.setTitle("Volleyball Lineup");
		vball.setSize(1100, 700);
		vball.addWindowListener(new WindowAdapter() {
		  public void windowClosing(WindowEvent e) {
			System.exit(0);
		  }
		});         
                
		vball.setVisible(true);
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); // what is this for?
 
		// Determine the new location of the window
		int w = vball.getSize().width;
		int h = vball.getSize().height;
		int x = (dim.width-w)/2;
		int y = (dim.height-h)/2;
		 
		// Move the window
		vball.setLocation(x, y);
                
                JPanel glassPane = new JPanel();
                glassPane.setOpaque(false);
                glassPane.setLayout(null);
                vball.setGlassPane(glassPane);
                vball.getGlassPane().setVisible(true);
                
                //add players
                String imagePath = "images/stickman.png";
                vball.addPlayer(imagePath, 500, 275,
                                "Bill", 
                                Player.Height.SHORT,
                                Player.Position.FRONT_CENTER,
                                Player.Role.SETTER);
                vball.addPlayer(imagePath, 400, 150,
                                "Sam", 
                                Player.Height.TALL,
                                Player.Position.FRONT_LEFT, 
                                Player.Role.POWER_HITTER);
                vball.addPlayer(imagePath, 400, 425,
                                "Bob", 
                                Player.Height.AVERAGE,
                                Player.Position.FRONT_RIGHT, 
                                Player.Role.WEAKSIDE_HITTER);
                vball.addPlayer(imagePath, 300, 275,
                                "Ryan", 
                                Player.Height.SHORT,
                                Player.Position.BACK_CENTER, //back center
                                Player.Role.SETTER); 
                vball.addPlayer(imagePath, 200, 150,
                                "Rob", 
                                Player.Height.AVERAGE,
                                Player.Position.BACK_LEFT, //back left
                                Player.Role.WEAKSIDE_HITTER); 
                vball.addPlayer(imagePath, 200, 425,
                                "Jon", 
                                Player.Height.TALL,
                                Player.Position.BACK_RIGHT, //back right
                                Player.Role.POWER_HITTER);
                
                // set initial team formation to 4-2
                //vball.setTeamFormation(Court.Formation.FORMATION_4_2);
                vball.setTeamFormation(Court.Formation.FORMATION_6_2);

	} // end main
} //end Volleyball class